package jheej5024;

public class J26_TypeCasting {

	//모든 클래스의 조상
    //모든 클래스는 자동적으로 java.lang.Object를 확장함
	//즉, Object 클래스는 자바에서 궁극의 super클래스임
	//기본적으로 Object 클래스에는 7개의 메서드가 정의되어 있고,
	//하위 클래스에서는 이것을 재정의해서 적절히 사용가능
	//equals - 기존 객체와 매개변수로 전달된 객체와 비교
	//         객체 비교가 제대로 이뤄질려면 메서드를 재정의하고 구현해야 함
	//hashcode - 객체의 해시코드를 출력함
	//           객체는 일반적으로 heap에 생성됨
	//           heap에 생성된 객체의 메모리 주소를 바탕으로 만들어지는 유일한 코드값을 의미
	//toString - 객체에 대한 설명을 출력함 
	
	//다형성 polymorphism
	//OOP의 중요 개념 중 하나
	//특정 유형의 프로그래밍 요소(변수)가 상황에 따라
	//다양한 유형의 요소로 바뀔 수 있는 특성을 의미
	//주로 상속관계에 있는 클래스간에서 나타나는 특별한 성질
	
	//is-a 관계확인
	//특정 객체가 어떤 유형과 동일한지
	//또는 상속관계인지 알아볼때
	//instanceof 예약어를 사용
	
	
	
	public static void main(String[] args) {
	Object obj = new Object();
	
	J25_Animal a = new J25_Animal();
	J25_Fish f = new J25_Fish();
	a = new J25_Fish();
	
	//Fish는 Animal을 확장했기 때문에
	//Animal 객체에 Fish 객체를 받을 수 있음
    //하위 객체를 상위 객체로 cast 하는 경우 이것을upcasting 이라 함	
	
	//f = (J25_Fish)new J25_Animal();
	//상위 객체를 하위 객체로 cast 하는 경우
	//이것을 downcasting 이라 함
	//이때 명시적으로 괄호안에 cast할 클래스 자료형을 명시
	
	//스타크래프트 게임내에서 해병, 불곰, 의무병을 생산하는 경우
	Marine m1 = new Marine();
	Firebat f1 = new Firebat();
	Medic  d1 = new Medic();

	//다형성을 근거로 테란유닛 생산 (upcasting)
	//즉, Marine 유닛은 상황에 따라 
	//TerranUnit도 될 수 있다는 의미
	
 	TerranUnits t1 = new Marine();
 	t1.sayUnit();
 	t1.sayUnit((Marine)t1);
	TerranUnits t2 = new Firebat();  //upcasting
	t2.sayUnit();
	t2.sayUnit((Firebat)t2);    //downcasting
	TerranUnits t3 = new Medic();
	t3.sayUnit((Medic)t3);
	
	
	AllianceUnit a1 = new Human();
	AllianceUnit a2 = new Wolf();
	AllianceUnit a3 = new Nom();
	
	//객체유형 확인하기
	J26_TypeCasting t = new J26_TypeCasting();
	
	if(t instanceof java.lang.Object)
		System.out.println( "t는 Object의 자손");
	
	if (m1 instanceof TerranUnits) //is-a
	System.out.println("해병은 테란유닛의자손");
	
	if (m1 instanceof Marine) //동질성
	System.out.println("m1은 해병임");
		
	
   }
 }

//TerranUnit - Marine,Firebat, Medic

class TerranUnits {
	public void sayUnit(){
		System.out.println( "저는 테란 유닛 입니다.");
	}
    
	public void sayUnit(Marine m){
		System.out.println( "저는 해병입니다.");
	}
	public void sayUnit(Firebat m){
		System.out.println( "저는 불곰입니다.");
	}
	public void sayUnit(Medic m){
		System.out.println( "저는 의무병입니다.");
	}

}


class Marine extends TerranUnits {}
class Firebat extends TerranUnits {}
class Medic extends TerranUnits {}




//AllianceUnit - Human, Wolf, Nom
class AllianceUnit {}
class Human extends AllianceUnit {}
class Wolf extends AllianceUnit {}
class Nom extends AllianceUnit {}


